package com.zyf.concurrency.chapter16;

import com.zyf.concurrency.annotations.NotThreadSafe;

/**
 * 双重检查加锁（不要这么做）
 * 引自原文：
 *      线程可能看到引用的当前值，但对象的状态值却是失效的，这意味着线程可以看到
 * 对象处于无效或错误的状态。
 *      在JMM的后续版本(Java 5.0以及更高的版本)中，如果把resource声明为volatile类型,
 * 那么就能启用DCL，并且这种方式对性能的影响很小，因为volatile变量读取操作的性能通常
 * 只是略高于非volatile 变量读取操作的性能。然而，DCL的这种使用方法已经被广泛地废弃
 * 了---促使该模式出现的驱动力(无竞争同步的执行速度很慢，以及JVM启动时很慢)已经
 * 不复存在，因而它不是一种高效的优化措施。延迟初始化占位类模式能带来同样的优势，并且
 * 更容易理解。
 * create by yifeng
 */
@NotThreadSafe
public class DoubleCheckedLocking {
    private static Resource resource;

    public static Resource getInstance() {
        if (resource == null) {
            synchronized (DoubleCheckedLocking.class) {
                if (resource == null) {
                    resource = new Resource();
                }
            }
        }
        return resource;
    }

    static class Resource {}
}
